package web.suzy.oj.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.lang.reflect.Method;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * YangSuzy 软件工作室
 * 类名: AsyncTaskConfig
 * 描述: 通用的异步线程池
 * 功能: ---- 待定 -----
 *
 * @author YangSuzy
 * Date: 2022/11/15 16:43
 */
@Configuration
@Slf4j(topic = "suzyoj")
public class AsyncTaskConfig implements AsyncConfigurer {

    /**
     * 方法名: getAsyncExecutor
     * 描述: 自定义线程池
     *
     * @return java.util.concurrent.Executor
     * @date 2022/11/15 16:43
     * @auther YangSuzy
     **/
    @Override
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        //线程池维护线程的最少数量
        taskExecutor.setCorePoolSize(10);
        //线程池维护线程的最大数量
        taskExecutor.setMaxPoolSize(20);
        //缓存队列
        taskExecutor.setQueueCapacity(200);
        //活跃时间
        taskExecutor.setKeepAliveSeconds(3);

        // 对拒绝task的处理策略
        //(1) 默认的ThreadPoolExecutor.AbortPolicy
        //    处理程序遭到拒绝将抛出运行时RejectedExecutionException;
        //(2) ThreadPoolExecutor.CallerRunsPolicy
        //    线程调用运行该任务的execute本身。此策略提供简单的反馈控制机制，能够减缓新任务的提交速度
        //(3) ThreadPoolExecutor.DiscardPolicy
        //    不能执行的任务将被删除;
        //(4) ThreadPoolExecutor.DiscardOldestPolicy
        //    如果执行程序尚未关闭，则位于工作队列头部的任务将被删除，然后重试执行程序
        //   （如果再次失败，则重复此过程）
        taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());

        //线程名前缀,方便排查问题
        taskExecutor.setThreadNamePrefix("CommonThread-");

        //必须初始化，否则在调用时会报线程池未初始化的异常
        taskExecutor.initialize();
        //返回自定义线程池
        return taskExecutor;
    }

    /**
     * 方法名: getAsyncUncaughtExceptionHandler
     * 描述: 异步任务中的异常处理
     *
     * @return org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler
     * @date 2022/11/15 16:49
     * @auther YangSuzy
     **/
    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return (arg0, arg1, arg2) -> {
            log.error("==========================" + arg0.getMessage() + "=======================", arg0);
            log.error("exception method:" + arg1.getName());
        };
    }
}
